use crate::src::struct_and_type::{
    Set, SetEntry, SetEqualFunc, SetFreeFunc, SetHashFunc, SetIterator, SetValue,
};
use :: libc;
extern "C" {
    fn malloc(_: u64) -> *mut libc::c_void;
    fn calloc(_: u64, _: u64) -> *mut libc::c_void;
    fn free(_: *mut libc::c_void);
}
static mut set_primes: [u32; 24] = [
    193 as i32 as u32,
    389 as i32 as u32,
    769 as i32 as u32,
    1543 as i32 as u32,
    3079 as i32 as u32,
    6151 as i32 as u32,
    12289 as i32 as u32,
    24593 as i32 as u32,
    49157 as i32 as u32,
    98317 as i32 as u32,
    196613 as i32 as u32,
    393241 as i32 as u32,
    786433 as i32 as u32,
    1572869 as i32 as u32,
    3145739 as i32 as u32,
    6291469 as i32 as u32,
    12582917 as i32 as u32,
    25165843 as i32 as u32,
    50331653 as i32 as u32,
    100663319 as i32 as u32,
    201326611 as i32 as u32,
    402653189 as i32 as u32,
    805306457 as i32 as u32,
    1610612741 as i32 as u32,
];
static mut set_num_primes: u32 = 0;
extern "C" fn set_allocate_table(mut set: *mut Set) -> i32 {
    if (unsafe { (*set).prime_index }) < (unsafe { set_num_primes }) {
        (unsafe { (*set).table_size = set_primes[(*set).prime_index as usize] });
    } else {
        (unsafe { (*set).table_size = ((*set).entries).wrapping_mul(10 as i32 as u32) });
    }
    (unsafe {
        (*set).table = calloc(
            (*set).table_size as u64,
            ::core::mem::size_of::<*mut SetEntry>() as u64,
        ) as *mut *mut SetEntry
    });
    return ((unsafe { (*set).table }) != 0 as *mut libc::c_void as *mut *mut SetEntry) as i32;
}
extern "C" fn set_free_entry(mut set: *mut Set, mut entry: *mut SetEntry) {
    if unsafe { ((*set).free_func).is_some() } {
        (unsafe { ((*set).free_func).expect("non-null function pointer")((*entry).data) });
    }
    (unsafe { free(entry as *mut libc::c_void) });
}
#[no_mangle]
pub extern "C" fn set_new(mut hash_func: SetHashFunc, mut equal_func: SetEqualFunc) -> *mut Set {
    let mut new_set: *mut Set = 0 as *mut Set;
    new_set = (unsafe { malloc(::core::mem::size_of::<Set>() as u64) }) as *mut Set;
    if new_set.is_null() {
        return 0 as *mut Set;
    }
    (unsafe { (*new_set).hash_func = hash_func });
    (unsafe { (*new_set).equal_func = equal_func });
    (unsafe { (*new_set).entries = 0 as i32 as u32 });
    (unsafe { (*new_set).prime_index = 0 as i32 as u32 });
    (unsafe { (*new_set).free_func = None });
    if set_allocate_table(new_set) == 0 {
        (unsafe { free(new_set as *mut libc::c_void) });
        return 0 as *mut Set;
    }
    return new_set;
}
#[no_mangle]
pub extern "C" fn set_free(mut set: *mut Set) {
    let mut rover: *mut SetEntry = 0 as *mut SetEntry;
    let mut next: *mut SetEntry = 0 as *mut SetEntry;
    let mut i: u32 = 0;
    i = 0 as i32 as u32;
    while i < (unsafe { (*set).table_size }) {
        rover = unsafe { *((*set).table).offset(i as isize) };
        while !rover.is_null() {
            next = unsafe { (*rover).next };
            set_free_entry(set, rover);
            rover = next;
        }
        i = i.wrapping_add(1);
        i;
    }
    (unsafe { free((*set).table as *mut libc::c_void) });
    (unsafe { free(set as *mut libc::c_void) });
}
#[no_mangle]
pub extern "C" fn set_register_free_function(mut set: *mut Set, mut free_func: SetFreeFunc) {
    (unsafe { (*set).free_func = free_func });
}
extern "C" fn set_enlarge(mut set: *mut Set) -> i32 {
    let mut rover: *mut SetEntry = 0 as *mut SetEntry;
    let mut next: *mut SetEntry = 0 as *mut SetEntry;
    let mut old_table: *mut *mut SetEntry = 0 as *mut *mut SetEntry;
    let mut old_table_size: u32 = 0;
    let mut old_prime_index: u32 = 0;
    let mut index: u32 = 0;
    let mut i: u32 = 0;
    old_table = unsafe { (*set).table };
    old_table_size = unsafe { (*set).table_size };
    old_prime_index = unsafe { (*set).prime_index };
    (unsafe { (*set).prime_index = ((*set).prime_index).wrapping_add(1) });
    (unsafe { (*set).prime_index });
    if set_allocate_table(set) == 0 {
        (unsafe { (*set).table = old_table });
        (unsafe { (*set).table_size = old_table_size });
        (unsafe { (*set).prime_index = old_prime_index });
        return 0 as i32;
    }
    i = 0 as i32 as u32;
    while i < old_table_size {
        rover = unsafe { *old_table.offset(i as isize) };
        while !rover.is_null() {
            next = unsafe { (*rover).next };
            index =
                (unsafe { ((*set).hash_func).expect("non-null function pointer")((*rover).data) })
                    .wrapping_rem(unsafe { (*set).table_size });
            (unsafe { (*rover).next = *((*set).table).offset(index as isize) });
            let fresh0 = unsafe { &mut (*((*set).table).offset(index as isize)) };
            *fresh0 = rover;
            rover = next;
        }
        i = i.wrapping_add(1);
        i;
    }
    (unsafe { free(old_table as *mut libc::c_void) });
    return 1 as i32;
}
#[no_mangle]
pub extern "C" fn set_insert(mut set: *mut Set, mut data: SetValue) -> i32 {
    let mut newentry: *mut SetEntry = 0 as *mut SetEntry;
    let mut rover: *mut SetEntry = 0 as *mut SetEntry;
    let mut index: u32 = 0;
    if (unsafe { (*set).entries })
        .wrapping_mul(3 as i32 as u32)
        .wrapping_div(unsafe { (*set).table_size })
        > 0 as i32 as u32
    {
        if set_enlarge(set) == 0 {
            return 0 as i32;
        }
    }
    index = (unsafe { ((*set).hash_func).expect("non-null function pointer")(data) })
        .wrapping_rem(unsafe { (*set).table_size });
    rover = unsafe { *((*set).table).offset(index as isize) };
    while !rover.is_null() {
        if (unsafe { ((*set).equal_func).expect("non-null function pointer")(data, (*rover).data) })
            != 0 as i32
        {
            return 0 as i32;
        }
        rover = unsafe { (*rover).next };
    }
    newentry = (unsafe { malloc(::core::mem::size_of::<SetEntry>() as u64) }) as *mut SetEntry;
    if newentry.is_null() {
        return 0 as i32;
    }
    (unsafe { (*newentry).data = data });
    (unsafe { (*newentry).next = *((*set).table).offset(index as isize) });
    let fresh1 = unsafe { &mut (*((*set).table).offset(index as isize)) };
    *fresh1 = newentry;
    (unsafe { (*set).entries = ((*set).entries).wrapping_add(1) });
    (unsafe { (*set).entries });
    return 1 as i32;
}
#[no_mangle]
pub extern "C" fn set_remove(mut set: *mut Set, mut data: SetValue) -> i32 {
    let mut rover: *mut *mut SetEntry = 0 as *mut *mut SetEntry;
    let mut entry: *mut SetEntry = 0 as *mut SetEntry;
    let mut index: u32 = 0;
    index = (unsafe { ((*set).hash_func).expect("non-null function pointer")(data) })
        .wrapping_rem(unsafe { (*set).table_size });
    rover = (unsafe { &mut *((*set).table).offset(index as isize) }) as *mut *mut SetEntry;
    while !(unsafe { *rover }).is_null() {
        if (unsafe {
            ((*set).equal_func).expect("non-null function pointer")(data, (**rover).data)
        }) != 0 as i32
        {
            entry = unsafe { *rover };
            (unsafe { *rover = (*entry).next });
            (unsafe { (*set).entries = ((*set).entries).wrapping_sub(1) });
            (unsafe { (*set).entries });
            set_free_entry(set, entry);
            return 1 as i32;
        }
        rover = unsafe { &mut (**rover).next };
    }
    return 0 as i32;
}
#[no_mangle]
pub extern "C" fn set_query(mut set: *mut Set, mut data: SetValue) -> i32 {
    let mut rover: *mut SetEntry = 0 as *mut SetEntry;
    let mut index: u32 = 0;
    index = (unsafe { ((*set).hash_func).expect("non-null function pointer")(data) })
        .wrapping_rem(unsafe { (*set).table_size });
    rover = unsafe { *((*set).table).offset(index as isize) };
    while !rover.is_null() {
        if (unsafe { ((*set).equal_func).expect("non-null function pointer")(data, (*rover).data) })
            != 0 as i32
        {
            return 1 as i32;
        }
        rover = unsafe { (*rover).next };
    }
    return 0 as i32;
}
#[no_mangle]
pub extern "C" fn set_num_entries(mut set: *mut Set) -> u32 {
    return unsafe { (*set).entries };
}
#[no_mangle]
pub extern "C" fn set_to_array(mut set: *mut Set) -> *mut SetValue {
    let mut array: *mut SetValue = 0 as *mut SetValue;
    let mut array_counter: i32 = 0;
    let mut i: u32 = 0;
    let mut rover: *mut SetEntry = 0 as *mut SetEntry;
    array = (unsafe {
        malloc((::core::mem::size_of::<SetValue>() as u64).wrapping_mul((*set).entries as u64))
    }) as *mut SetValue;
    if array.is_null() {
        return 0 as *mut SetValue;
    }
    array_counter = 0 as i32;
    i = 0 as i32 as u32;
    while i < (unsafe { (*set).table_size }) {
        rover = unsafe { *((*set).table).offset(i as isize) };
        while !rover.is_null() {
            let fresh2 = unsafe { &mut (*array.offset(array_counter as isize)) };
            *fresh2 = unsafe { (*rover).data };
            array_counter += 1;
            array_counter;
            rover = unsafe { (*rover).next };
        }
        i = i.wrapping_add(1);
        i;
    }
    return array;
}
#[no_mangle]
pub extern "C" fn set_union(mut set1: *mut Set, mut set2: *mut Set) -> *mut Set {
    let mut iterator: SetIterator = SetIterator {
        set: 0 as *mut Set,
        next_entry: 0 as *mut SetEntry,
        next_chain: 0,
    };
    let mut new_set: *mut Set = 0 as *mut Set;
    let mut value: SetValue = 0 as *mut libc::c_void;
    new_set = set_new(unsafe { (*set1).hash_func }, unsafe { (*set1).equal_func });
    if new_set.is_null() {
        return 0 as *mut Set;
    }
    set_iterate(set1, &mut iterator);
    while set_iter_has_more(&mut iterator) != 0 {
        value = set_iter_next(&mut iterator);
        if set_insert(new_set, value) == 0 {
            set_free(new_set);
            return 0 as *mut Set;
        }
    }
    set_iterate(set2, &mut iterator);
    while set_iter_has_more(&mut iterator) != 0 {
        value = set_iter_next(&mut iterator);
        if set_query(new_set, value) == 0 as i32 {
            if set_insert(new_set, value) == 0 {
                set_free(new_set);
                return 0 as *mut Set;
            }
        }
    }
    return new_set;
}
#[no_mangle]
pub extern "C" fn set_intersection(mut set1: *mut Set, mut set2: *mut Set) -> *mut Set {
    let mut new_set: *mut Set = 0 as *mut Set;
    let mut iterator: SetIterator = SetIterator {
        set: 0 as *mut Set,
        next_entry: 0 as *mut SetEntry,
        next_chain: 0,
    };
    let mut value: SetValue = 0 as *mut libc::c_void;
    new_set = set_new(unsafe { (*set1).hash_func }, unsafe { (*set2).equal_func });
    if new_set.is_null() {
        return 0 as *mut Set;
    }
    set_iterate(set1, &mut iterator);
    while set_iter_has_more(&mut iterator) != 0 {
        value = set_iter_next(&mut iterator);
        if set_query(set2, value) != 0 as i32 {
            if set_insert(new_set, value) == 0 {
                set_free(new_set);
                return 0 as *mut Set;
            }
        }
    }
    return new_set;
}
#[no_mangle]
pub extern "C" fn set_iterate(mut set: *mut Set, mut iter: *mut SetIterator) {
    let mut chain: u32 = 0;
    (unsafe { (*iter).set = set });
    (unsafe { (*iter).next_entry = 0 as *mut SetEntry });
    chain = 0 as i32 as u32;
    while chain < (unsafe { (*set).table_size }) {
        if !(unsafe { *((*set).table).offset(chain as isize) }).is_null() {
            (unsafe { (*iter).next_entry = *((*set).table).offset(chain as isize) });
            break;
        } else {
            chain = chain.wrapping_add(1);
            chain;
        }
    }
    (unsafe { (*iter).next_chain = chain });
}
#[no_mangle]
pub extern "C" fn set_iter_next(mut iterator: *mut SetIterator) -> SetValue {
    let mut set: *mut Set = 0 as *mut Set;
    let mut result: SetValue = 0 as *mut libc::c_void;
    let mut current_entry: *mut SetEntry = 0 as *mut SetEntry;
    let mut chain: u32 = 0;
    set = unsafe { (*iterator).set };
    if (unsafe { (*iterator).next_entry }).is_null() {
        return 0 as *mut libc::c_void;
    }
    current_entry = unsafe { (*iterator).next_entry };
    result = unsafe { (*current_entry).data };
    if !(unsafe { (*current_entry).next }).is_null() {
        (unsafe { (*iterator).next_entry = (*current_entry).next });
    } else {
        (unsafe { (*iterator).next_entry = 0 as *mut SetEntry });
        chain = (unsafe { (*iterator).next_chain }).wrapping_add(1 as i32 as u32);
        while chain < (unsafe { (*set).table_size }) {
            if !(unsafe { *((*set).table).offset(chain as isize) }).is_null() {
                (unsafe { (*iterator).next_entry = *((*set).table).offset(chain as isize) });
                break;
            } else {
                chain = chain.wrapping_add(1);
                chain;
            }
        }
        (unsafe { (*iterator).next_chain = chain });
    }
    return result;
}
#[no_mangle]
pub extern "C" fn set_iter_has_more(mut iterator: *mut SetIterator) -> i32 {
    return ((unsafe { (*iterator).next_entry }) != 0 as *mut libc::c_void as *mut SetEntry) as i32;
}
extern "C" fn run_static_initializers_set() {
    (unsafe {
        set_num_primes = (::core::mem::size_of::<[u32; 24]>() as u64)
            .wrapping_div(::core::mem::size_of::<i32>() as u64) as u32
    });
}
#[used]
#[cfg_attr(target_os = "linux", link_section = ".init_array")]
#[cfg_attr(target_os = "windows", link_section = ".CRT$XIB")]
#[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
static INIT_ARRAY: [unsafe extern "C" fn(); 1] = [run_static_initializers_set];
